/**
 * 漆水河 脚手架基础公开课
 * 2022/8/13 --- 2022/12/13
 * 有疑问可加QQ群: 809126489，后续会持续输出与大家一起成长
 */
package com.qishuihe.basedomain.infrastructure.aspect.log;



import com.alibaba.fastjson2.JSONObject;
import com.qishuihe.basedomain.infrastructure.mq.ProductMessageHandler;
import com.qishuihe.basedomain.infrastructure.vo.LogVO;
import com.qishuihe.basedomain.infrastructure.vo.LoginUserVO;
import io.swagger.annotations.ApiOperation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;


/**
 * 用户日志记录
 */
@Component
@Aspect
public class LogAspect {

    @Autowired
    private ProductMessageHandler productMessageHandler;

    private int MAX_LENGTH=500;
    private String ANONYMOUS_USER = "anonymousUser";

    @Pointcut(value="@annotation(com.qishuihe.basedomain.infrastructure.aspect.LogAnnotation)")
    public void annotationPointCut(){}

    @Around("annotationPointCut()")
    Object  doLog(ProceedingJoinPoint joinPoint ) throws Throwable {

        // 获取实现类的接口
        Class<?>[] class_ =  joinPoint.getTarget().getClass().getInterfaces();

        String methodName=joinPoint.getSignature().getName();
        Object[] arguments=joinPoint.getArgs();


        Class<?> classTarget=joinPoint.getTarget().getClass();
        Class<?>[] par=((MethodSignature) joinPoint.getSignature()).getParameterTypes();
        Method objMethod=classTarget.getMethod(methodName, par);
        objMethod =class_[0].getMethod(methodName,par);

        ApiOperation apiOperation=objMethod.getAnnotation(ApiOperation.class);


        LogVO logEntity = new LogVO();
        logEntity.setOperation(apiOperation.value());
        logEntity.setDesc_(apiOperation.notes());
        String str = JSONObject.toJSONString(arguments);
        //防止数据库放不下
        str =str.length()>MAX_LENGTH?str.substring(0,MAX_LENGTH-3)+"...":str;
        logEntity.setParam(str);
        //获取当前登陆人信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication.getPrincipal().toString().contains(ANONYMOUS_USER)){
            logEntity.setCreateBy("0");
            logEntity.setCreateDate(new Date());
        }else {
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = (UsernamePasswordAuthenticationToken) authentication;
            LoginUserVO loginUserDTO = (LoginUserVO)usernamePasswordAuthenticationToken.getPrincipal();
            logEntity.setCreateBy(String.valueOf(loginUserDTO.getId()));
            logEntity.setCreateDate(new Date());
        }

        productMessageHandler.sendLog(logEntity);
        return joinPoint.proceed();
    }

}
